warn and refuse to autoenable a special remote when name is in use
authorJoey Hess <joeyh@joeyh.name>
Thu, 14 Aug 2025 15:05:42 +0000 (11:05 -0400)
committerJoey Hess <joeyh@joeyh.name>
Thu, 14 Aug 2025 15:05:42 +0000 (11:05 -0400)
Improve behavior when there are special remotes configured with
autoenable=yes with names that conflict with other remotes.

The use of remoteList' is to avoid using the cached remote list in the case
where there are two special remotes both configured to autoenable and both
with the same name. Once the 1st is autoenabled, this makes reload the
remote list and so see the 1st, and so refuse to autoenable the second.

This adds a little bit of overhead, but it should be sufficiently small not
to need optimising.

Sponsored-by: Dartmouth College's OpenNeuro project
Annex/SpecialRemote.hs
CHANGELOG
doc/bugs/multiple_records_in_remote.log_for_the_same_remote.mdwn
doc/bugs/multiple_records_in_remote.log_for_the_same_remote/comment_3_fe26531dcfa26b30225dc34a841153d1._comment
doc/bugs/multiple_records_in_remote.log_for_the_same_remote/comment_4_87330e2378759679069ab0fce1df3e92._comment [new file with mode: 0644]

index 2b23b06b5ded2ce0f832acbd449f1812ace3da58..d3b1215b63c351deb88ec4a729a2b4309a8a85ea 100644 (file)
@@ -96,12 +96,7 @@ autoEnable = do
                        Just (Sameas u') -> u'
                        Nothing -> cu
                case (lookupName c, findType c) of
-                       -- Avoid auto-enabling when the name contains a
-                       -- control character, because git does not avoid
-                       -- displaying control characters in the name of a
-                       -- remote, and an attacker could leverage
-                       -- autoenabling it as part of an attack.
-                       (Just name, Right t) | safeOutput name == name -> do
+                       (Just name, Right t) -> checkcanenable u name $ do
                                showSideAction $ UnquotedString $ "Auto enabling special remote " ++ name
                                dummycfg <- liftIO dummyRemoteGitConfig
                                tryNonAsync (setup t (AutoEnable c) (Just u) Nothing c dummycfg) >>= \case
@@ -117,6 +112,19 @@ autoEnable = do
        getcu r = fromMaybe
                (Remote.uuid r)
                (remoteAnnexConfigUUID (Remote.gitconfig r))
+       checkcanenable u name cont
+               -- Avoid auto-enabling when the name contains a control
+               -- character, because git does not avoid displaying control
+               -- characters in the name of a remote, and an attacker could
+               -- leverage autoenabling it as part of an attack.
+               | safeOutput name /= name = return ()
+               | otherwise = do
+                       rs <- remoteList' False
+                       case filter (\rmt -> Remote.name rmt == name) rs of
+                               (rmt:_) | Remote.uuid rmt /= u -> warning $ 
+                                       UnquotedString $ "Cannot auto enable special remote " 
+                                               ++ name ++ " because there is another remote with the same name."
+                               _ -> cont
 
 autoEnableable :: Annex (M.Map UUID RemoteConfig)
 autoEnableable = do
index 16580febc0723384de66b372a76781bf7d73b6f0..adba28c4d43d925239b033bca1d1581ce5a49f36 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -14,6 +14,8 @@ git-annex (10.20250722) UNRELEASED; urgency=medium
     to be explicitly set.
   * info: Added --show option to pick which parts of the info to calculate
     and display.
+  * Improve behavior when there are special remotes configured with
+    autoenable=yes with names that conflict with other remotes.
   * Bump aws build dependency to 0.24.1.
   * stack.yaml: Update to lts-24.2.
 
index d7682da4137b143c99378b587d5ce76896680d60..c79f9980f74eadfa45d707f655844ec5c9a69306 100644 (file)
@@ -71,3 +71,6 @@ ATM 10.20240430+git26-g5f61667f27-1~ndall+1 but I guess it is unrelated.
 [[!meta author=yoh]]
 [[!tag projects/openneuro]]
 [[!meta title="warn when two special remotes with the same name are both configured to autoenable, and avoid one overwriting the git config of the other"]]
+
+> I think I have explained what happened here, and the behavior change is
+> enough to prevent the confusing behavior. [[done]] --[[Joey]]
index 46dbb73d94b380787e2ffac5cb89750af1fa3f10..e43e88f275df16b40b97d65a5514df872cad2733 100644 (file)
@@ -3,8 +3,8 @@
  subject="""comment 3"""
  date="2025-08-14T14:03:08Z"
  content="""
-Beyond a warning, it would be possible two autoenable both, but use a new
-name for the second one.
+Beyond a warning, it would be possible to autoenable both, but use a new
+name for the second one. Although that could lead to its own problems.
 
 It occurs to me that it's also possible for autoenable of a special remote
 to overwrite/change the git config of a regular git remote that has the
diff --git a/doc/bugs/multiple_records_in_remote.log_for_the_same_remote/comment_4_87330e2378759679069ab0fce1df3e92._comment b/doc/bugs/multiple_records_in_remote.log_for_the_same_remote/comment_4_87330e2378759679069ab0fce1df3e92._comment
new file mode 100644 (file)
index 0000000..62cbd15
--- /dev/null
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 4"""
+ date="2025-08-14T14:58:11Z"
+ content="""
+I've added a warning in these cases, and it will avoid autoenabling a special
+remote when there is already a remote with the same name. 
+
+In the case of two special remotes with the same name that are both set to
+autoenable, it's essentially random which gets enabled first and so "wins".
+
+Decided against autoenabling it with a different name, because: a) There's
+the potential that the name it comes up with is actually the name of
+another special remote that is also due to be autoenabled. b) It seems like
+potentially confusing behavior for there to be a remote with a different
+name than that usually used for a particular special remote.
+"""]]